/**
 * @file    CTimerCommand.hpp
 * @date    2014-06-22
 * @author  Vladimir Prokopovich VProkopovich@gmail.com
 * @brief   Class CTimerCommand header file.
 *          An internal representation of a timer
 */

#ifndef CTIMERCOMMAND_HPP
#define CTIMERCOMMAND_HPP

static unsigned int gLastId = 0U;

class CTimerCommand
{
   public:

      // Data types section

      enum eTimerType
      {
         TIMER_TYPE_INVALID = -1,
         TIMER_TYPE_ONCE = 0,
         TIMER_TYPE_REPEAT = 1,
         TIMER_TYPE_BOTH = 2
      };
      typedef eTimerType tTimerType;
      typedef void (*tCallbackFunction)(void*);

      // Methods section

      /**
       * @brief Constructor
       * @param pData      The data object that would be sent to callback fucntion
       * @param callback   Callback function that would be called when timer is fired
       * @param intervalRepeat   Repeat interval
       * @param intervalOnce     Once interval
       */
      CTimerCommand(void* pData, tCallbackFunction callback, const unsigned long long int& intervalRepeat, const unsigned long long int& intervalOnce, const tTimerType& type);

      /**
       * @brief   Calculates next fire time depending on type of timer and start time (or previous fire time)
       * @return  returned value is an absolute value - timestamp in future
       */
      const unsigned long long int getNextFireTime() const;

      /**
       * @brief Updates object`s state
       *        This method should be called from dispatcher every time when 
       *        this timer fired.
       */
      void timerFired();

      // Getters
      inline unsigned int getId();
      inline tCallbackFunction getCallback();
      inline void* getData();
      inline const tTimerType getType();
   private:
   
      // methods section

      /**
       * Default constructor
       * Unimplemented to avoid misusing
       */
      CTimerCommand();

      // members section

      unsigned int mId;
      void* mpData;
      tCallbackFunction mCallback;
      unsigned long long int mTimestamp;
      unsigned long long int mIntervalRepeat;
      unsigned long long int mIntervalOnce;
      tTimerType mType;
      bool mFiredOnce;
};

unsigned int CTimerCommand::getId()
{
   return mId;
}

CTimerCommand::tCallbackFunction CTimerCommand::getCallback()
{
   return mCallback;
}

void* CTimerCommand::getData()
{
   return mpData;
}

const CTimerCommand::tTimerType CTimerCommand::getType()
{
   return mType;
}

#endif // CTIMERCOMMAND_HPP